home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / artemis1 / src / filemenu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-14  |  21.9 KB  |  919 lines

  1. /*
  2.     ARTemis (Graphic Editor for FM-TOWNS)
  3.     (c) MATSUUCHI Ryosuke 1992,1993
  4.  
  5.     filemenu.c
  6. */
  7.  
  8. // #define    DEBUG
  9.  
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <dos.h>
  13. #include <malloc.h>
  14. #include <ctype.h>
  15.  
  16. #include "ge.h"
  17. #include <direct.h>
  18. #include "dispman.h"
  19.  
  20.  
  21. #define    GETITEMXY(n)    menu_getbuttonxy(NULL,(n),&ix,&iy,NULL,NULL)
  22. #define    GETITEMXYS(n)    menu_getbuttonxy(NULL,(n),&ix,&iy,&ixlen,&iylen)
  23.  
  24.  
  25. #define    CHARWID    6
  26. #define    CHARHT    12
  27.  
  28. /*--------------------------------------------------------*/
  29. /*                     メニューの定義                     */
  30. /*--------------------------------------------------------*/
  31.  
  32.  
  33. #define    FLISTX        168
  34. #define    FLISTY        57
  35. #define    FLISTYLEN    12*10
  36. #define    FLISTXLEN    6*24
  37. #define    FNAMEX        16
  38. #define    FNAMEY        184
  39. #define    FNAMEXLEN    (6*46+2)
  40. #define    PATHX        74
  41. #define    PATHY        22
  42. #define    PATHXLEN    (6*37+2)
  43. #define    MASKX        74
  44. #define    MASKY        38
  45. #define    MASKXLEN    (6*37+2)
  46. #define    EXTX        12
  47. #define    EXTY        76
  48. #define    DRVX        (16+12)
  49. #define    DRVY        38
  50. #define    DRVXW        30
  51. #define    DRVYW        16
  52.  
  53. /*
  54. #define    itemFName    2
  55. #define    itemFList    3
  56. #define    itemPath    5
  57. #define    itemMask    7
  58. #define    itemExec    8
  59. #define    itemCancel    9
  60. #define    itemDiskF    11
  61. #define    itemDriveInc    14
  62. #define    itemDriveDec    13
  63. #define    itemDrive    15
  64. #define    itemX        16
  65. */
  66. #define    itemX_num    16
  67.  
  68. #define    itemFormat    10
  69. #define    itemFCTiff    11
  70. #define    itemFTiff    12
  71. #define    itemFBeTa    13
  72.  
  73.  
  74. static void disp_fname(),disp_now_path(),disp_mask_name();
  75.  
  76. static void dspNameList(int pos);
  77. #define    XITEMMAX    10
  78. static SELECTOR_ELEMENT filemenu_selx[XITEMMAX];
  79. #define    SELPARA(n)        (setup_sel[n].var)
  80. static void disp_filemenu(), erase_filemenu();
  81.  
  82. #include "filemenu.md"
  83.  
  84. /*--------------------------------------------------------*/
  85. /*                     内部変数の宣言                     */
  86. /*--------------------------------------------------------*/
  87.  
  88.  
  89. #define    DIRMA    1    /* 0=ディレクトリバッファをいちいち確保  1=まとめて確保 */
  90.  
  91. typedef struct
  92. {
  93. #if (DIRMA==1)
  94.     char    name[15];
  95. #else
  96.     char    *name;
  97. #endif
  98.     bool    subdir;    // ディレクトリ属性付きのエントリなら YES
  99.     long    size;
  100. } DIR;
  101.  
  102.  
  103. #define    MAXWILD    300
  104. #if (DIRMA==1)
  105. static    DIR        *namelist = NULL;
  106. #else
  107. static    bool    list_inited = NO;
  108. static    DIR        namelist[MAXWILD];
  109. #endif
  110. static    int        namenum;
  111.  
  112. static    char    fname[128] = {0};
  113. static    char    nowpath[128] = "ARTemis_non_initialized";
  114. static    char    mask[128] = "*.*";
  115. static    int        csrx = 0;                // ファイル名編集カーソルの位置
  116. static    int        nowdrive = -1;            // 現在表示しているドライブ
  117. // ドライブ選択状態 3 とおり
  118. #define    DISPLAY        0
  119. #define    SELECTING    1
  120. #define    INVALID        2
  121. static    int        drive_selecting = DISPLAY;
  122. static    int        cur_diskfree = -1;        // 選択ドライブの残り容量
  123.  
  124. static unsigned _curdrive;
  125. static char _curpath[128];
  126.  
  127.  
  128. /*--------------------------------------------------------*/
  129. /*                        補助処理                        */
  130. /*--------------------------------------------------------*/
  131.  
  132.  
  133. // ■ ディスクの残り容量を得る
  134. //---------------------------------------------------------------------------
  135.  
  136. static int diskfree(int drive)
  137. // drive: 0=デフォルト 1=A 2=B ...
  138. // 返値: -1=ドライブ指定が無効、0以上=残りバイト数
  139. {
  140.     struct diskfree_t info;
  141.     if (_dos_getdiskfree(drive,&info) != 0)
  142.         return -1;
  143.     unsigned long ac,spc,bps;
  144.     ac = info.avail_clusters;
  145.     spc = info.sectors_per_cluster;
  146.     bps = info.bytes_per_sector;
  147.     return ac*spc*bps;
  148. }
  149.  
  150.  
  151. // ■ ディスクの残り容量を表示する
  152. //---------------------------------------------------------------------------
  153.  
  154. static void disp_diskfree()
  155. {
  156.     int x,y;
  157.     // int drive;
  158.     // if (nowpath[1] == ':')
  159.     //     drive = toupper(nowpath[0]) - 'A' + 1;
  160.     // else
  161.     //     drive = 0;
  162.     int ix,iy;
  163.     GETITEMXY(itemDiskF);
  164.     x = ix,  y = iy;
  165.     grboxfill(x,y,CHARWID*6,CHARHT,DMgetmenuplt(COL_menu),DrawNORMAL);
  166.     if (drive_selecting == DISPLAY)
  167.     {
  168.         char msgbuf[10];
  169.         sprintf(msgbuf, "%6d", cur_diskfree/1024);
  170.         ARTputstr12(x,y,msgbuf,DMgetmenuplt(White),DMgetmenuplt(COL_menu));
  171.     }
  172. }
  173.  
  174.  
  175. // ■ ディレクトリ上のファイル名一覧を得る
  176. //---------------------------------------------------------------------------
  177.  
  178.  
  179. #define    attrSUBDIR    0x10
  180.  
  181.  
  182. static int getdir()
  183. // 返値 0=成功  -1=メモリ不足
  184. {
  185.     struct find_t dirbuf;
  186.     char pathbuf[128], pathbuf2[128];
  187.     int r;
  188.     DEBUG_MSG("getdir begin");
  189.     namenum = 0;
  190.     r = 0;
  191.     //
  192.     // ディレクトリ内容を記憶するバッファを確保する
  193. #if (DIRMA==1)
  194.     if (namelist == NULL)
  195.     {
  196.         if ((namelist = calloc(sizeof(DIR), MAXWILD)) == NULL)
  197.             { r = -1;  goto getdir_end; }
  198.     }
  199. #else
  200.     if (!list_inited)
  201.     {
  202.         int i;
  203.         for (i=0; i<MAXWILD; i++)
  204.             namelist[i].name = NULL;
  205.         list_inited = YES;
  206.     }
  207. #endif
  208.     //
  209.     // 読み込むディレクトリのフルパス名を作る
  210.     strcpy(pathbuf,nowpath);
  211.     if (strlen(pathbuf) > 0)
  212.     {
  213.         if (pathbuf[strlen(pathbuf)-1] != '\\')
  214.             strcat(pathbuf,"\\");
  215.     }
  216.     //
  217.     if (strcmp(mask, "*.*") == 0)
  218.     {
  219.         //
  220.         // ファイル名マスクが "*.*" である場合は、全ディレクトリ要素を
  221.         // 一度に読む
  222.         strcat(pathbuf,mask);
  223.         if (_dos_findfirst(pathbuf, _A_SUBDIR, &dirbuf) == 0)
  224.         {
  225.             do
  226.             {
  227.                 DIR *dp = namelist + namenum;
  228.                 if (strcmp(dirbuf.name,".") == 0)
  229.                     continue;
  230. #if (DIRMA==0)
  231.                 if (dp->name != NULL)
  232.                     free(dp->name);
  233.                 if ((dp->name = malloc(strlen(dirbuf.name)+1)) == NULL)
  234.                     { r = -1;  goto getdir_end; }
  235. #endif
  236.                 if (strcmp(dirbuf.name,"..") == 0)
  237.                     strcpy(dp->name, "親ディレクトリ");
  238.                 else
  239.                     strcpy(dp->name, dirbuf.name);
  240.                 dp->subdir = ((dirbuf.attrib & attrSUBDIR)!=0 ? YES : NO);
  241.                 dp->size = dirbuf.size;
  242.                 namenum++;
  243.             } while (_dos_findnext(&dirbuf) == 0 && namenum < MAXWILD);
  244.         }
  245.     }
  246.     else
  247.     {
  248.         //
  249.         // ファイル名マスクが "*.*" でない場合は、まずサブディレクトリ名を
  250.         // しらべ、次にファイル名を調べる
  251.         strcpy(pathbuf2, pathbuf);
  252.         strcat(pathbuf, "*.*");
  253.         if (_dos_findfirst(pathbuf, _A_SUBDIR, &dirbuf) == 0)
  254.         {
  255.             do
  256.             {
  257.                 if ((dirbuf.attrib & attrSUBDIR) == 0 || strcmp(dirbuf.name,".") == 0)
  258.                     continue;
  259.                 DIR *dp = namelist + namenum;
  260. #if (DIRMA==0)
  261.                 if (dp->name != NULL)
  262.                     free(dp->name);
  263.                 if ((dp->name = malloc(strlen(dirbuf.name)+1)) == NULL)
  264.                     { r = -1;  goto getdir_end; }
  265. #endif
  266.                 if (strcmp(dirbuf.name,"..") == 0)
  267.                     strcpy(dp->name, "親ディレクトリ");
  268.                 else
  269.                     strcpy(dp->name, dirbuf.name);
  270.                 dp->subdir = ((dirbuf.attrib & attrSUBDIR)!=0 ? YES : NO);
  271.                 dp->size = dirbuf.size;
  272.                 namenum++;
  273.             } while (_dos_findnext(&dirbuf) == 0 && namenum < MAXWILD);
  274.         }
  275.         strcpy(pathbuf, pathbuf2);
  276.         strcat(pathbuf, mask);
  277.         if (_dos_findfirst(pathbuf, _A_RDONLY, &dirbuf) == 0)
  278.         {
  279.             do
  280.             {
  281.                 DIR *dp;
  282.                 dp = namelist + namenum;
  283. #if (DIRMA==0)
  284.                 if (dp->name != NULL)
  285.                     free(dp->name);
  286.                 if ((dp->name = malloc(strlen(dirbuf.name)+1)) == NULL)
  287.                     { r = -1;  goto getdir_end; }
  288. #endif
  289.                 strcpy(dp->name, dirbuf.name);
  290.                 dp->subdir = ((dirbuf.attrib & attrSUBDIR)!=0 ? YES : NO);
  291.                 dp->size = dirbuf.size;
  292.                 namenum++;
  293.             } while (_dos_findnext(&dirbuf) == 0 && namenum < MAXWILD);
  294.         }
  295.     }
  296. getdir_end:
  297.     sprintf(debugmsg,"getdir end(%d)",r);
  298.     DEBUG_MSG(debugmsg);
  299.     return r;
  300. }
  301.  
  302.  
  303. // ■ メニューにファイル名リストを表示する
  304. //---------------------------------------------------------------------------
  305.  
  306.  
  307. static char dspFnameList_reset = YES;
  308.  
  309.  
  310. static void disp_onefname(int pos, int ofs) // ファイルネーム1つを表示する
  311. {
  312.     int ix,iy,ixlen,iylen;
  313.     GETITEMXYS(itemFList);
  314.     DIR *dp;
  315.     char strbuf[80];
  316.     dp = namelist + pos + ofs;
  317.     if (dp->subdir)
  318.         sprintf(strbuf,"<%s>",dp->name);
  319.     else
  320.         sprintf(strbuf,"%-14s%10d",dp->name,dp->size);
  321.     ARTputstr12(ix,iy+ofs*CHARHT,strbuf,DMgetmenuplt(White),DMgetmenuplt(Black));
  322. }
  323.  
  324.  
  325. static void dspNameList_new(int pos)
  326. {
  327.     int i,ix,iy,ixlen,iylen;
  328.     GETITEMXYS(itemFList);
  329.     grboxfill(ix-1,iy-1,ixlen+2,iylen+2,DMgetmenuplt(Black),DrawNORMAL);
  330.     if (drive_selecting == DISPLAY)
  331.     {
  332.         for (i = 0;  i < iylen/CHARHT && pos+i < namenum;  i++)
  333.             disp_onefname(pos,i);
  334.     }
  335.     else if (drive_selecting == SELECTING)
  336.         putmsg_width(ix,iy+(iylen-CHARHT*2)/2, ixlen-2,
  337.                      "ドライブ名を左クリックしてください",DMgetmenuplt(White));
  338.     else if (drive_selecting == INVALID)
  339.         putmsg_width(ix,iy+(iylen-CHARHT*2)/2, ixlen-2,
  340.                      "ドライブの準備ができていません",DMgetmenuplt(White));
  341.     dspFnameList_reset = FALSE;
  342. }
  343.  
  344.  
  345. static void dspNameList(int pos)
  346. {
  347.     static int prepos = -1;
  348.     int ix,iy,ixlen,iylen;
  349.     GETITEMXYS(itemFList);
  350.     // grboxfill(ix,iy,ixlen,iylen,DMgetmenuplt(Black),DrawNORMAL);
  351.     // for (i = 0;  i < iylen/CHARHT && pos+i < namenum;  i++)
  352.     if (   drive_selecting != DISPLAY || dspFnameList_reset
  353.         || _abs(pos-prepos) >= iylen/CHARHT)
  354.         dspNameList_new(pos);
  355.     else if (pos == prepos)
  356.         ;
  357.     else
  358.     {
  359.         char gbuf[FLISTXLEN*CHARHT*2];
  360.         if (pos > prepos)    // 上へのスクロール
  361.         {
  362.             int i,mov,ynum;
  363.             mov = pos - prepos;
  364.             ynum = iylen/CHARHT;
  365.             for (i=0; i < ynum-mov; i++)
  366.             {
  367.                 grp_getblk(gbuf, ix,iy+CHARHT*(i+mov), ixlen,CHARHT);
  368.                 grp_putblk(ix,iy+CHARHT*i,ixlen,CHARHT, gbuf, DrawNORMAL);
  369.             }
  370.             grboxfill(ix,iy+(ynum-mov)*CHARHT,ixlen,CHARHT*mov,DMgetmenuplt(Black),DrawNORMAL);
  371.             for (i=0; i<mov; i++)
  372.                 disp_onefname(pos,ynum-mov+i);
  373.         }
  374.         else // 下へのスクロール
  375.         {
  376.             int i,mov,ynum;
  377.             mov = prepos - pos;
  378.             ynum = iylen/CHARHT;
  379.             for (i=ynum-1-mov; i >= 0; i--)
  380.             {
  381.                 grp_getblk(gbuf, ix,iy+CHARHT*i, ixlen,CHARHT);
  382.                 grp_putblk(ix,iy+CHARHT*(i+mov),ixlen,CHARHT, gbuf, DrawNORMAL);
  383.             }
  384.             grboxfill(ix,iy,ixlen,CHARHT*mov,DMgetmenuplt(Black),DrawNORMAL);
  385.             for (i=0; i<mov; i++)
  386.             {
  387.                 disp_onefname(pos,i);
  388.             }
  389.         }
  390.     }
  391.     dspFnameList_reset = FALSE;
  392.     prepos = pos;
  393. }
  394.  
  395.  
  396. // ■ メニューに現在(選択/入力中)のファイル名を表示する
  397. //---------------------------------------------------------------------------
  398.  
  399.  
  400. static void disp_fname()
  401. {
  402.     int ix,iy,ixlen,iylen;
  403.     GETITEMXYS(itemFName);
  404.     int x,y;
  405.     x = ix, y = iy;
  406.     grboxfill(x,y,ixlen,iylen,DMgetmenuplt(Black),DrawNORMAL);
  407.     ARTputstr12(x+1,y+1,fname,DMgetmenuplt(White),DMgetmenuplt(Black));
  408.     if (csrx > strlen(fname))
  409.         csrx = strlen(fname);
  410.     // grboxfill(x+1+csrx*8,y+1,8,16,White,DrawXOR);
  411. }
  412.  
  413.  
  414. // ■ メニューに現在のパス名を表示する
  415. //---------------------------------------------------------------------------
  416.  
  417.  
  418. static void disp_now_path()
  419. {
  420.     int ix,iy,ixlen,iylen;
  421.     GETITEMXYS(itemPath);
  422.     int x,y;
  423.     x = ix, y = iy;
  424.     grboxfill(x,y,ixlen,iylen,DMgetmenuplt(COL_menu),DrawNORMAL);
  425.     ARTputstr12(x+1,y+1,nowpath,DMgetmenuplt(White),DMgetmenuplt(COL_menu));
  426. }
  427.  
  428.  
  429. // ■ メニューに現在のマスク文字列を表示する
  430. //---------------------------------------------------------------------------
  431.  
  432.  
  433. static void disp_mask_name()
  434. {
  435.     int ix,iy,ixlen,iylen;
  436.     GETITEMXYS(itemMask);
  437.     int x,y;
  438.     x = ix,  y = iy;
  439.     grboxfill(x,y,ixlen,iylen,DMgetmenuplt(Black),DrawNORMAL);
  440.     ARTputstr12(x+1,y+1,mask,DMgetmenuplt(White),DMgetmenuplt(Black));
  441. }
  442.  
  443.  
  444. // ■ 文字列を編集する
  445. //---------------------------------------------------------------------------
  446.  
  447.  
  448. int    editStr(int x,int y,int clmnum, char *buf,int buflen, int csrx)
  449. // 返値:  0=RETURNキー終了   1=ESCキー終了
  450. {
  451.     char dspbuf[200];
  452.     int msx,msy;
  453.     msx = ms.x;
  454.     msy = ms.y;
  455.     if (csrx == -1)
  456.         csrx = strlen(buf);
  457.     else if (csrx > strlen(buf))
  458.         csrx = strlen(buf);
  459.     bool abort;
  460.     int dspofs;    // 文字列を何文字目から表示するか
  461.     abort = NO;
  462.     dspofs = 0;
  463.     for (;;)
  464.     {
  465.         // 文字列の表示 (表示位置の調節も行う)
  466.         grboxfill(x,y,clmnum*CHARWID,CHARHT,DMgetmenuplt(Black),DrawNORMAL);
  467.         if ((csrx-dspofs) > (clmnum-1))
  468.             dspofs = csrx-(clmnum-1);
  469.         else if ((csrx-dspofs) < 0)
  470.             dspofs = csrx;
  471.         {int t; for(t=0;t<clmnum;t++) dspbuf[t]=buf[dspofs+t]; dspbuf[t]=0;}
  472.         // strncpy(dspbuf,buf+dspofs,clmnum);
  473.         ARTputstr12(x,y,dspbuf,DMgetmenuplt(White),DMgetmenuplt(Black));
  474.         grboxfill(x+(csrx-dspofs)*CHARWID,y,CHARWID,CHARHT,DMgetmenuplt(White),DrawXOR);
  475.         // ユーザーのアクション待ち
  476.         do
  477.             { ms_get(&ms); ms.x = msx; ms.y = msy; }
  478.         while (ms.btn1==OFF && ms.btn2==OFF && key_chk()==0);
  479.         if (ms.btn1 == OFFON)
  480.             goto _endloop;
  481.         if (ms.btn2 == OFFON)
  482.         {
  483.             abort = YES;
  484.             goto _endloop;
  485.         }
  486.         // 入力文字に対応する処理
  487.         int c;
  488.         c = key_read();
  489.         switch (c)
  490.         {
  491.         case 13:                                // RETURN キー
  492.             goto _endloop;
  493.         case 27:                                // ESC キー
  494.             abort = YES;
  495.             goto _endloop;
  496.         case 8:                                    // BS キー
  497.             if (csrx > 0)
  498.             {
  499.                 memcpy(buf+csrx-1,buf+csrx,strlen(buf+csrx)+1);
  500.                 csrx--;
  501.             }
  502.             break;
  503.         case 127:                                // DEL キー
  504.             if (strlen(buf+csrx) > 0)
  505.                 memcpy(buf+csrx,buf+csrx+1,strlen(buf+csrx+1)+1);
  506.             break;
  507.         case 28:                                // 右カーソルキー
  508.             if (strlen(buf+csrx) > 0)
  509.                 csrx++;
  510.             break;
  511.         case 29:                                // 左    〃
  512.             if (csrx > 0)
  513.                 csrx--;
  514.             break;
  515.         case 30:                                 // 上    〃
  516.             csrx = 0;
  517.             break;
  518.         case 31:                                // 下    〃
  519.             csrx = strlen(buf);
  520.             break;
  521.         default:
  522.             if (' '<=c && c!=127)                 // 通常文字
  523.             {
  524.                 if (strlen(buf)+1 < buflen)
  525.                 {
  526.                     _rmemcpy(buf+csrx+1,buf+csrx,strlen(buf+csrx)+1);
  527.                     *(buf+csrx) = c;
  528.                     csrx++;
  529.                 }
  530.             }
  531.         }
  532.     }
  533. _endloop:
  534.     // 文字列の表示
  535.     grboxfill(x,y,clmnum*CHARWID,CHARHT,DMgetmenuplt(Black),DrawNORMAL);
  536.     strncpy(dspbuf, buf, clmnum);
  537.     ARTputstr12(x,y,dspbuf,DMgetmenuplt(White),DMgetmenuplt(Black));
  538.     //
  539.     return (abort ? 1 : 0);
  540. }
  541.  
  542.  
  543. // ■ ドライブ名の表示
  544. //---------------------------------------------------------------------------
  545.  
  546.  
  547. static void disp_drivename(void)
  548. {
  549.     int ix,iy,ixlen,iylen;
  550.     GETITEMXYS(itemDrive);
  551.     char *str = "A:";
  552.     *str = 'A' + (nowdrive-1);
  553.     grboxfill(ix,iy, ixlen,iylen, DMgetmenuplt(COL_menu),DrawNORMAL);
  554.     menu_drawbox(ix,iy,ixlen,iylen);
  555.     ARTputstr12(ix+3,iy+2,str,DMgetmenuplt(COL_menuString),DMgetmenuplt(COL_menu));
  556. }
  557.  
  558.  
  559. /*--------------------------------------------------------*/
  560. /*              ファイルメニューの描画・消去               */
  561. /*--------------------------------------------------------*/
  562.  
  563.  
  564. static void disp_filemenu( /* int x, int y */ )
  565. {
  566.     disp_diskfree();
  567.     disp_drivename();
  568. }
  569.  
  570.  
  571. static void erase_filemenu( /* int x, int y */ )
  572. {
  573.     dspFnameList_reset = YES;
  574. }
  575.  
  576.  
  577. /*--------------------------------------------------------*/
  578. /*       ファイルメニューモジュールの初期化/後処理       */
  579. /*--------------------------------------------------------*/
  580.  
  581.  
  582. int filemenu_init()
  583. {
  584.     if (namelist == NULL)
  585.     {
  586.         if ((namelist = calloc(sizeof(DIR), MAXWILD)) == NULL)
  587.             return -1;
  588.     }
  589.     _dos_getdrive(&_curdrive);
  590.     _getcwd(_curpath,128);
  591.     return 0;
  592. }
  593.  
  594.  
  595. void filemenu_end(void)
  596. {
  597.     unsigned dmy;
  598.     _dos_setdrive(_curdrive, &dmy);
  599.     _chdir(_curpath);
  600. }
  601.  
  602.  
  603. /*--------------------------------------------------------*/
  604. /*                    ファイルメニュー                    */
  605. /*--------------------------------------------------------*/
  606.  
  607. #define    XSEL    2000
  608.  
  609. #if 0
  610. static int check_drive(char drivename)
  611. {
  612.     struct diskfree_t dinfo;
  613.     return _dos_getdiskfree(toupper(drivename) - 'A' + 1, &dinfo);
  614. }
  615. #endif
  616.  
  617.  
  618. void file_menu_exp(char *title, void (*exec_func)(char **filelist, int x),
  619.                    char **xitem)
  620. /*
  621.     xitem : 文字列の配列へのポインタ(or NULL)
  622.             xitem[0] = タイトル(太字で表示)
  623.             xitem[1..] = 各アイテム(NULLでエンドマーク)
  624. */
  625. {
  626.     PRINT("file_menu_exp begin\n");
  627.     char FNAME[50];  int r;
  628.     {
  629.         PRINT("拡張アイテム設定...");
  630.         static SELECTOR_ELEMENT buf;
  631.         #define    TITLEX    EXTX
  632.         #define    MEMBERX    (EXTX+6)
  633.         int i;
  634.         BUTTON *bp = menu_button(&filemenu, itemX);
  635.         KNOW(bp!=NULL);
  636.         for (i=0; i<itemX_num; i++,bp++)
  637.         {
  638.             *bp = btnpart[0];
  639.             menu_button_setid(bp,itemX+i);
  640.         }
  641.         TRACE;
  642.         if (xitem != NULL)
  643.         {
  644.             int y = EXTY, n = 0;
  645.             for (i = 0;  xitem[i] != NULL; )
  646.             {
  647.                 TRACE;
  648.                 SEL *sel = menu_selector_new();
  649.                 if (sel == NULL) break;
  650.                 int j = 0;
  651.                 while (xitem[i+j] != NULL && *xitem[i+j] != '\0')
  652.                 {
  653.                     TRACE;
  654.                     if (j == 0)
  655.                     {
  656.                         BUTTON *bp = menu_button(&filemenu, itemX /* +n */  );
  657.                         KNOW(bp!=NULL);
  658.                         *bp = btnpart[1];
  659.                         menu_button_setid(bp,itemX);
  660.                         menu_button_setxy(bp,TITLEX,y);
  661.                         menu_button_setvar(bp,(int)xitem[i+j]);
  662.                     }
  663.                     else
  664.                     {
  665.                         /* j>=1 */
  666.                         SEL_E *ep = menu_selector_element_new();
  667.                         if(ep==NULL) goto ENDLOOP;
  668.                         menu_selector_element_setxy(ep,j==0?TITLEX:MEMBERX,y);
  669.                         menu_selector_element_setstr(ep,xitem[i+j]);
  670.                         menu_selector_addelement(sel,ep);
  671.                     }
  672.                     TRACE;
  673.                     y += CHARHT + 4;
  674.                     j++;
  675.                 }
  676.                 i += j;
  677.                 if (xitem[i] != NULL)
  678.                     i++;
  679.                 y += 4;
  680.                 n++;
  681.                 menu_selector_setid(sel,XSEL);
  682.                 menu_addselector(&filemenu, sel);
  683.             }
  684.             ENDLOOP:
  685.             ;
  686.         }
  687.         PRINT("拡張アイテム設定終了");
  688.     }
  689.  
  690.     PRINT("file_menu_exp ディレクトリ読み込み\n");
  691.     if (strcmp(nowpath, "ARTemis_non_initialized") == 0)
  692.     {
  693.         if (_getcwd(nowpath,128) == NULL)
  694.             return;
  695.     }
  696.     nowdrive = toupper(nowpath[0]) - 'A' + 1;
  697.     if ((cur_diskfree = diskfree(nowdrive)) >= 0)
  698.     {
  699.         drive_selecting = DISPLAY;
  700.         PRINT("file_menu_exp ディレクトリ読み込み a\n");
  701.         if (getdir() != 0)
  702.         {
  703.             dispAttentionMsg("ディレクトリ内容を記憶するための"
  704.                              "メモリが不足しています");
  705.             goto file_menu_end;
  706.         }
  707.     }
  708.     else
  709.     {
  710.         drive_selecting = INVALID;
  711.     }
  712.     PRINT("file_menu_exp ディレクトリ読み込み b\n");
  713.     menu_settitle(&filemenu, title);
  714.     FNAME[0] = 0;  r=2;
  715.     //
  716.     DEBUG_MSG("file_menu_exp メニュー表示");
  717.     if (!menu_ifdisp())            // 通常メニューとして表示する
  718.         menu_disp(&filemenu);
  719.     else                        // サブメニューとして表示する
  720.         menu_dispxy(-2, -2, &filemenu);
  721.     SCROLLBAR *bp;
  722.     bp = menu_scrollbar(&filemenu,barFLIST);
  723.     menu_scrollbar_setallsize(bp,_max(FLISTYLEN/CHARHT, namenum));
  724.     menu_scrollbar_setdispsize(bp,FLISTYLEN/CHARHT);
  725.     #define LISTPOS    menu_scrollbar_getvar(bp)
  726.     for (;;)
  727.     {
  728.         DMdispcsr(ms.x,ms.y);
  729.         do
  730.         {
  731.             ms_get(&ms);
  732.         } while (ms.dx==0 && ms.dy==0 && ms.btn1==OFF && ms.btn2==OFF &&
  733.                  key_chk()==0);
  734.         DMerasecsr();
  735.         scrollForCsr(1,1);
  736.         if (ms.btn1 == OFFON)
  737.         {
  738.             int a, ix,iy,ixlen,iylen;
  739.             int fnum; int ax,ay; SCROLLBAR *sbarp;
  740.             a = menu_where(ms.x,ms.y,&filemenu, &ax,&ay,&sbarp);
  741.             switch (a)
  742.             {
  743.             case itemScrollBar:
  744.                 menu_touchscrollbar(sbarp, ax,ay);
  745.                 break;
  746.             case itemDriveInc:
  747.                 if (drive_selecting != SELECTING)
  748.                 {
  749.                     drive_selecting = SELECTING;
  750.                     dspNameList_new(LISTPOS);
  751.                 }
  752.                 nowdrive++;
  753.                 if ('A'+nowdrive-1 > 'Q')
  754.                     nowdrive = 1;
  755.                 disp_drivename();
  756.                 break;
  757.             case itemDriveDec:
  758.                 if (drive_selecting != SELECTING)
  759.                 {
  760.                     drive_selecting = SELECTING;
  761.                     dspNameList_new(LISTPOS);
  762.                 }
  763.                 nowdrive--;
  764.                 if (nowdrive < 1)
  765.                     nowdrive = 'Q'-'A'+1;
  766.                 disp_drivename();
  767.                 break;
  768.             case itemDrive:
  769.                 if ((cur_diskfree = diskfree(nowdrive)) >= 0)
  770.                 {
  771.                     drive_selecting = DISPLAY;
  772.                     unsigned dmy;
  773.                     _dos_setdrive(nowdrive, &dmy);
  774.                     _getcwd(nowpath,128);
  775.                     getdir();
  776.                     menu_scrollbar_setallsize
  777.                         (bp,_max(FLISTYLEN/CHARHT,namenum));
  778.                     menu_scrollbar_setvar(bp,0);
  779.                 }
  780.                 else
  781.                 {
  782.                     drive_selecting = INVALID;
  783.                     namenum = 0;
  784.                     menu_scrollbar_setallsize
  785.                         (bp,_max(FLISTYLEN/CHARHT, namenum));
  786.                     menu_scrollbar_setvar(bp,0);
  787.                     strcpy(nowpath, "A:");
  788.                     nowpath[0] = 'A' + nowdrive - 1;
  789.                 }
  790.                 dspNameList_new(LISTPOS);
  791.                 menu_makeupscrollbar(bp);
  792.                 disp_now_path();
  793.                 disp_diskfree();
  794.                 break;
  795.             case itemFList:
  796.                 fnum = LISTPOS + ay/CHARHT;
  797.                 if (fnum < namenum)
  798.                 {
  799.                     DIR *namep;
  800.                     namep = namelist + fnum;
  801.                     if (namep->subdir)
  802.                     {
  803.                         if (strcmp(namep->name,"親ディレクトリ") == 0)
  804.                         {
  805.                             char *p;
  806.                             if ((p = strrchr(nowpath,'\\')) != NULL)
  807.                                 *p = 0;    // そこを文字列の終端にする
  808.                         }
  809.                         else if (strcmp(namep->name,".") != 0)
  810.                         {
  811.                             if (nowpath[strlen(nowpath)-1] != '\\')
  812.                                 strcat(nowpath,"\\");
  813.                             strcat(nowpath,namep->name);
  814.                         }
  815.                         _chdir(nowpath);
  816.                         getdir();
  817.                         menu_scrollbar_setallsize
  818.                             (bp,_max(FLISTYLEN/CHARHT, namenum));
  819.                         menu_scrollbar_setvar(bp,0);
  820.                         dspNameList_new(LISTPOS);
  821.                         menu_makeupscrollbar(bp);
  822.                         disp_now_path();
  823.                     }
  824.                     else
  825.                     {
  826.                         strcpy(fname, namep->name);
  827.                         disp_fname();
  828.                     }
  829.                 }
  830.                 break;
  831.             case itemFName:
  832.                 GETITEMXYS(itemFName);
  833.                 r = (editStr(ix+1,iy+1,ixlen/6,fname,128,-1)==0? 1: 2);
  834.                 // goto _endloop;
  835.                 continue;
  836.             #if 0
  837.             case itemPath:
  838.                 GETITEMXYS(itemPath);
  839.                 editStr(ix+1,iy+1,ixlen/6, nowpath,128, -1);
  840.                 getdir();
  841.                 menu_scrollbar_setallsize
  842.                     (bp,_max(FLISTYLEN/CHARHT, namenum));
  843.                 menu_scrollbar_setvar(bp,0);
  844.                 dspNameList_new(LISTPOS);
  845.                 menu_makeupscrollbar(bp);
  846.                 disp_diskfree();
  847.                 break;
  848.             #endif
  849.             case itemMask:
  850.                 DEBUG_MSG("filemenu mask-1");
  851.                 GETITEMXYS(itemMask);
  852.                 editStr(ix+1,iy+1,ixlen/6, mask,128, -1);
  853.                 getdir();
  854.                 DEBUG_MSG("filemenu mask-2");
  855.                 menu_scrollbar_setallsize
  856.                     (bp,_max(FLISTYLEN/CHARHT, namenum));
  857.                 menu_scrollbar_setvar(bp,0);
  858.                 dspNameList_new(LISTPOS);
  859.                 DEBUG_MSG("filemenu mask-3");
  860.                 menu_makeupscrollbar(bp);
  861.                 DEBUG_MSG("filemenu mask-4");
  862.                 break;
  863.             case itemMoveMenu:
  864. MOVEMENU:
  865.                 menu_move();
  866.                 break;
  867.             case itemExec:
  868.                 if (drive_selecting == DISPLAY)
  869.                 {
  870.                     r = 1;
  871.                     goto _endloop;
  872.                 }
  873.                 else
  874.                     goto MOVEMENU;
  875.             case itemCancel:
  876.                 r = 2;
  877.                 goto _endloop;
  878.             case itemSelector:
  879.                 menu_touchselector(&filemenu);
  880.                 break;
  881.             }
  882.         }
  883.         else if (ms.btn2 == OFFON)
  884.             { r=2; break; }
  885.     }
  886. _endloop:
  887.     menu_erase();
  888.     PRINT("メニュー消去完了");
  889.     if (r==1 && fname[0]!=0)
  890.     {
  891.         char fnbuf[128]; char *fnlist[200];
  892.         if (strchr(fname, '\\') == NULL)
  893.         {
  894.             strcpy(fnbuf,nowpath);
  895.             if (fnbuf[strlen(fnbuf)-1] != '\\')
  896.                 strcat(fnbuf,"\\");
  897.             strcat(fnbuf,fname);
  898.         }
  899.         else
  900.             strcpy(fnbuf,fname);
  901.         fnlist[0] = fnbuf;
  902.         fnlist[1] = NULL;
  903.         SEL *sel = menu_selector(&filemenu,XSEL);
  904.         (*exec_func)(fnlist,(sel!=NULL?menu_selector_getvar(sel):0));
  905.     }
  906.     menu_clearselector(&filemenu);
  907. file_menu_end:
  908.     PRINT("file_menu_exp end\n");
  909. }
  910.  
  911.  
  912. void file_menu(char *title, void (*exec_func)(char **filelist))
  913. {
  914.     file_menu_exp(title, (void(*)(char **filelist,int x))exec_func, NULL);
  915. }
  916.  
  917.  
  918. /* end of filemenu.c */
  919.